//
//  JSBridgeCamera.swift
//  ToBeBigFE
//
//  Created by mingo on 2020/2/12.
//  Copyright © 2020 com.example. All rights reserved.
//

import Foundation
import UIKit
import MobileCoreServices
import AVKit
import CoreFoundation

class JSBridgeCamera : BridgeModuelBase {

    weak var viewController: WebViewController?
    
    fileprivate var cameraDelegate: CameraDelegate?

    init(viewController: WebViewController) {
        self.viewController = viewController
    }

    override func callFunc(_ funcName: String, callbackId: String, arg: [String : Any?]) {
        switch funcName {
        case "takePicture": takePicture(callbackId: callbackId, arg: arg)
        case "takeVideo": takeVideo(callbackId: callbackId, arg: arg)
        default: break
        }
    }
    
    private func takePicture(callbackId: String, arg: [String : Any?]) {
        guard let vc = self.viewController else { return }
        // 设备不支持Camera
        if !UIImagePickerController.isSourceTypeAvailable(.camera) {
            callback(callbackId: callbackId, json: [
                "success": false,
                "error": "This device is not support camera"
            ])
            return
        }
        
        DispatchQueue.main.async {
            let cameraPicker = UIImagePickerController()
            // 配置为拍照图片
            cameraPicker.allowsEditing = false
            cameraPicker.sourceType = .camera
            cameraPicker.cameraCaptureMode = .photo
            
            // 创建delegate
            self.cameraDelegate = CameraDelegate()
            self.cameraDelegate?.jsbridgeCamera = self
            self.cameraDelegate?.callbackId = callbackId
            cameraPicker.delegate = self.cameraDelegate!
            
            // 打开拍照
            vc.present(cameraPicker, animated: true, completion: nil)
        }
    }
    
    private func takeVideo(callbackId: String, arg: [String : Any?]) {
        guard let vc = self.viewController else { return }
        if !UIImagePickerController.isSourceTypeAvailable(.camera) {
            callback(callbackId: callbackId, json: [
                "success": false,
                "error": "This device is not support camera"
            ])
            return
        }
        DispatchQueue.main.async {
            let cameraPicker = UIImagePickerController()
            cameraPicker.sourceType = .camera
            cameraPicker.cameraDevice = .rear
            cameraPicker.videoQuality = .typeHigh
            cameraPicker.mediaTypes = [kUTTypeMovie] as [String]
            cameraPicker.videoMaximumDuration = 60
            cameraPicker.videoExportPreset = AVAssetExportPresetHighestQuality
            self.cameraDelegate = CameraDelegate()
            self.cameraDelegate?.jsbridgeCamera = self
            self.cameraDelegate?.callbackId = callbackId
            cameraPicker.delegate = self.cameraDelegate!
            vc.present(cameraPicker, animated: true, completion: nil)
        }
    }
}

fileprivate class CameraDelegate : NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    weak var jsbridgeCamera: JSBridgeCamera?
    var callbackId: String!
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        jsbridgeCamera?.cameraDelegate = nil
        picker.dismiss(animated: true, completion: nil)
        
        // 判断是视频资源
        if let url = info[.mediaURL] as? URL {
            // callback给js
            jsbridgeCamera?.callback(callbackId: callbackId, json: [
                "success": true,
                "file": url.absoluteString
            ])
        }
        // 判断是图片资源
        else if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            // 创建临时文件
            let tempDir = NSTemporaryDirectory() as NSString
            let appTempDir = tempDir.appendingPathComponent(Bundle.main.bundleIdentifier!) as NSString
            let cacheDir = appTempDir.appendingPathComponent("Camera") as NSString
            let filePath = cacheDir.appendingPathComponent("Camera_\(Int64(Date().timeIntervalSince1970)).jpg")
            let fileMgr = FileManager.default
            
            // 确定目录存在
            var isDir: ObjCBool = false
            if !fileMgr.fileExists(atPath: cacheDir as String, isDirectory: &isDir) {
                try? fileMgr.createDirectory(atPath: cacheDir as String, withIntermediateDirectories: true, attributes: nil)
            }
            
            // 转换成jpeg data
            guard let data = image.jpegData(compressionQuality: 1) else {
                jsbridgeCamera?.callback(callbackId: callbackId, json: [
                    "success": false,
                    "error": "Image compress fail"
                ])
                return
            }
            
            // 写文件
            do {
                let fileURL = URL(fileURLWithPath: filePath)
                try data.write(to: fileURL)
                // callback给js
                jsbridgeCamera?.callback(callbackId: callbackId, json: [
                    "success": true,
                    "file": fileURL.absoluteString,
                    "type": "image/jpeg"
                ])
            } catch {
                jsbridgeCamera?.callback(callbackId: callbackId, json: [
                    "success": false,
                    "error": error.localizedDescription
                ])
                return
            }
        } else {
            jsbridgeCamera?.callback(callbackId: callbackId, json: [
                "success": false,
                "error": "Operation failed."
            ])
        }
    }
    
    
    // 出来用户取消的操作
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        jsbridgeCamera?.cameraDelegate = nil
        picker.dismiss(animated: true, completion: nil)
        jsbridgeCamera?.callback(callbackId: callbackId, json: [
            "success": false,
            "canceled": true
        ])
    }
    
}
